package com.gzc.just.play.last.war.balanceserver.handler;



import com.gzc.just.play.last.war.common.handler.SimpleMessageHandler;

import com.gzc.just.play.last.war.balanceserver.manager.ServerManager;

import io.netty.channel.ChannelHandlerContext;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;



import java.util.HashMap;

import java.util.Map;



/**

 * 鍋ュ悍妫鏌ュ勭悊鍣

 * 澶勭悊鏈嶅姟鍣ㄥ仴搴锋鏌ョ浉鍏崇殑娑堟伅

 */

@Component("balance-healthCheckHandler")
public class HealthCheckHandler implements SimpleMessageHandler {

    private static final Logger logger = LoggerFactory.getLogger(HealthCheckHandler.class);

    

    @Autowired

    private ServerManager serverManager;

    

    private static final int HEALTH_CHECK = 2004;

    

    @Override

    public void handle(Object message, ChannelHandlerContext ctx) throws Exception {

        // 浠庝笂涓嬫枃涓鑾峰彇鏈嶅姟鍣↖D锛堝傛灉鏄鏈嶅姟鍣ㄨ嚜韬鍙戦佺殑蹇冭烦锛

        io.netty.util.AttributeKey<Long> serverIdKey = io.netty.util.AttributeKey.valueOf("serverId");

        Long serverId = ctx.channel().attr(serverIdKey).get();

        

        if (serverId != null) {

            // 澶勭悊鏈嶅姟鍣ㄥ彂閫佺殑蹇冭烦娑堟伅

            handleServerHeartbeat(serverId, message, ctx);

        } else {

            // 澶勭悊瀹㈡埛绔璇锋眰鐨勫仴搴锋鏌ユ秷鎭

            handleClientHealthCheck(message, ctx);

        }

    }

    

    /**

     * 澶勭悊鏈嶅姟鍣ㄥ彂閫佺殑蹇冭烦娑堟伅

     */

    private void handleServerHeartbeat(Long serverId, Object message, ChannelHandlerContext ctx) {

        // 浠庢秷鎭涓瑙ｆ瀽鏈嶅姟鍣ㄧ姸鎬

        Map<String, Object> serverStatus = extractServerStatus(message);

        

        // 鏇存柊鏈嶅姟鍣ㄧ姸鎬

        if (serverManager.updateServerStatus(serverId, serverStatus)) {

            logger.info("Received heartbeat from server: {}", serverId);

            

            // 鍙戦佸績璺崇‘璁ゅ搷搴

            sendHeartbeatResponse(ctx, true, "Heartbeat received");

        } else {

            logger.warn("Failed to update status for server: {}", serverId);

            

            // 鍙戦佸績璺冲け璐ュ搷搴

            sendHeartbeatResponse(ctx, false, "Failed to update server status");

        }

    }

    

    /**

     * 澶勭悊瀹㈡埛绔璇锋眰鐨勫仴搴锋鏌ユ秷鎭

     */

    private void handleClientHealthCheck(Object message, ChannelHandlerContext ctx) {

        // 浠庢秷鎭涓瑙ｆ瀽瑕佹鏌ョ殑鏈嶅姟鍣↖D锛堝傛灉鏈夛級

        Long targetServerId = extractTargetServerId(message);

        

        Map<String, Object> healthStatus;

        if (targetServerId != null) {

            // 鑾峰彇鐗瑰畾鏈嶅姟鍣ㄧ殑鍋ュ悍鐘舵

            healthStatus = serverManager.getServerHealthStatus(targetServerId);

            

            // 鍙戦佸仴搴锋鏌ュ搷搴

            if (healthStatus != null) {

                sendHealthCheckResponse(ctx, healthStatus, true, "Server health status retrieved");

                logger.info("Client requested health check for server: {}", targetServerId);

            } else {

                sendHealthCheckResponse(ctx, null, false, "Server not found: " + targetServerId);

                logger.warn("Client requested health check for non-existent server: {}", targetServerId);

            }

        } else {

            // 鑾峰彇骞宠　鏈嶅姟鍣ㄨ嚜韬鐨勫仴搴风姸鎬

            healthStatus = new HashMap<>();

            healthStatus.put("serverId", 0); // 骞宠　鏈嶅姟鍣↖D

            healthStatus.put("serverType", "balance");

            healthStatus.put("status", "healthy");

            healthStatus.put("uptime", System.currentTimeMillis() - serverManager.getStartTime());

            healthStatus.put("activeConnections", serverManager.getActiveConnectionCount());

            healthStatus.put("totalServers", serverManager.getTotalServerCount());

            

            sendHealthCheckResponse(ctx, healthStatus, true, "Balance server health status");

            logger.info("Client requested balance server health check");

        }

    }

    

    private Map<String, Object> extractServerStatus(Object message) {

        // 瀹為檯瀹炵幇涓搴旇ヤ粠娑堟伅瀵硅薄涓瑙ｆ瀽鏈嶅姟鍣ㄧ姸鎬

        // 杩欓噷杩斿洖绀轰緥鍊

        return Map.of(

            "load", 50, // 绀轰緥璐熻浇

            "status", "running", // 绀轰緥鐘舵

            "memory", 1024, // 绀轰緥鍐呭瓨浣跨敤(MB)

            "cpu", 30 // 绀轰緥CPU浣跨敤鐜(%)

        );

    }

    

    private Long extractTargetServerId(Object message) {

        // 瀹為檯瀹炵幇涓搴旇ヤ粠娑堟伅瀵硅薄涓瑙ｆ瀽鐩鏍囨湇鍔″櫒ID

        // 杩欓噷杩斿洖null琛ㄧず妫鏌ュ钩琛℃湇鍔″櫒鑷韬

        return null;

    }

    

    private void sendHeartbeatResponse(ChannelHandlerContext ctx, boolean success, String message) {

        // 瀹為檯瀹炵幇涓搴旇ユ瀯閫犲苟鍙戦佸績璺冲搷搴旀秷鎭

        logger.info("Sending heartbeat response: success={}, message={}", success, message);

    }

    

    private void sendHealthCheckResponse(ChannelHandlerContext ctx, Map<String, Object> healthStatus, 

                                       boolean success, String message) {

        // 瀹為檯瀹炵幇涓搴旇ユ瀯閫犲苟鍙戦佸仴搴锋鏌ュ搷搴旀秷鎭

        logger.info("Sending health check response: success={}, message={}", success, message);

        

        // 绀轰緥锛氭墦鍗板仴搴风姸鎬佸唴瀹癸紙瀹為檯瀹炵幇涓搴旇ュ皢鐘舵佸簭鍒楀寲涓哄搷搴旀秷鎭锛

        if (success && healthStatus != null) {

            logger.debug("Health status content:");

            for (Map.Entry<String, Object> entry : healthStatus.entrySet()) {

                logger.debug("{}: {}", entry.getKey(), entry.getValue());

            }

        }

    }



    @Override

    public int getMessageId() {

        return HEALTH_CHECK;

    }

    

    @Override

    public String getName() {

        return "HealthCheckHandler";

    }

    

    @Override

    public Logger getLogger() {

        return logger;

    }

}